home *** CD-ROM | disk | FTP | other *** search
- Program Fractal_Map;
- { This program draws a triangular fractal landscape. }
- { It takes a triangle, bisects the edges, and adjusts}
- { there height a proportional amount; then it does it}
- { all over again with the smaller triangles generated}
- { up to the maxt number of triangles per side. }
- { It takes about 30 sec to calculate, then 30 to draw}
- { }
- { Scott R. Burke -- 1986,87 }
- { }
-
- const
- maxt = 33; { number of subdivisions of the triangle }
- frac = 5; { ?? }
-
- type
- point = record
- x,y,z : real;
- c:integer;
- end;
-
- var
- mat : array[1..maxt,1..maxt] of point;
- i,j,k : integer;
- l,m,n : real;
- ch : char;
- depth : real;
- min,max : real;
- levela,levelb:real;
-
-
-
- procedure dofold(ai,aj,bi,bj,ci,cj:integer);
- { take the triangle anchored at (ai,aj),(bi,bj),(ci,cj) }
- { and generate new heights for the midpoints of each }
- { side of the triangle (a',b',c') }
-
- label 99;
- type
- matcoord = record i,j : integer; end;
- var
- ap,bp,cp : matcoord;
- l : real;
- begin
- if (abs(ai-bi)=1)or(abs(aj-bj)=1) then goto 99; { skip procedure }
-
- {***************************** A PRIME ***********************************}
- { calculate a prime }
- ap.i := (ai+bi) div 2;
- ap.j := (aj+bj) div 2;
-
- { get the coordinate values for a prime }
- mat[ap.i,ap.j].x := (mat[ai,aj].x + mat[bi,bj].x) / 2;
- mat[ap.i,ap.j].y := (mat[ai,aj].y + mat[bi,bj].y) / 2;
- mat[ap.i,ap.j].z := (mat[ai,aj].z + mat[bi,bj].z) / 2;
- { calculate new height }
- l := sqrt(sqr(mat[ai,aj].x-mat[bi,bj].x)+sqr(mat[ai,aj].y-mat[bi,bj].y));
- mat[ap.i,ap.j].z := mat[ap.i,ap.j].z + (2*(random-0.5)/frac)*l;
-
- {***************************** B PRIME ***********************************}
- { calculate b prime }
- bp.i := (ai+ci) div 2;
- bp.j := (aj+cj) div 2;
-
- { get the coordinate values for b prime }
- mat[bp.i,bp.j].x := (mat[ai,aj].x + mat[ci,cj].x) / 2;
- mat[bp.i,bp.j].y := (mat[ai,aj].y + mat[ci,cj].y) / 2;
- mat[bp.i,bp.j].z := (mat[ai,aj].z + mat[ci,cj].z) / 2;
- { calculate new height }
- l := sqrt(sqr(mat[ai,aj].x-mat[ci,cj].x)+sqr(mat[ai,aj].y-mat[ci,cj].y));
- mat[bp.i,bp.j].z := mat[bp.i,bp.j].z + (2*(random-0.5)/frac)*l;
-
- {***************************** C PRIME ***********************************}
- { calculate c prime }
- cp.i := (bi+ci) div 2;
- cp.j := (bj+cj) div 2;
-
- { get the coordinate values for a prime }
- mat[cp.i,cp.j].x := (mat[bi,bj].x + mat[ci,cj].x) / 2;
- mat[cp.i,cp.j].y := (mat[bi,bj].y + mat[ci,cj].y) / 2;
- mat[cp.i,cp.j].z := (mat[bi,bj].z + mat[ci,cj].z) / 2;
- { calculate new height }
- l := sqrt(sqr(mat[ci,cj].x-mat[bi,bj].x)+sqr(mat[ci,cj].y-mat[bi,bj].y));
- mat[cp.i,cp.j].z := mat[cp.i,cp.j].z + (2*(random-0.5)/frac)*l;
-
- {**************** do next level ******************************************}
- dofold(ai,aj,ap.i,ap.j,bp.i,bp.j);
- dofold(bp.i,bp.j,ci,cj,cp.i,cp.j);
- dofold(ap.i,ap.j,bi,bj,cp.i,cp.j);
- dofold(ap.i,ap.j,bp.i,bp.j,cp.i,cp.j);
- 99: { procedure skipped }
- end;
-
-
-
- procedure plot_triangle(i,j:integer);
- var
- ax,ay,bx,by,cx,cy,l1,l2,l3 : integer;
-
- function adjx(x,y:real):integer;
- { adjust the x-coord for tilted perspective }
- begin
- adjx := round(783.00*(x-50.00)/(261.00+y))+160;
- end;
-
- function adjy(y,z:real):integer;
- { adjust the y-coord for tilted perspective }
- begin
- adjy := 200 - round((z*500.00)/(261.00+y));
- end;
-
- begin
- { figure the adjusted x-screen values for a,b and c }
- ax := adjx(mat[i,j].x,mat[i,j].y);
- bx := adjx(mat[i+1,j+1].x,mat[i+1,j+1].y);
- cx := adjx(mat[i+1,j].x,mat[i+1,j].y);
-
- { figure the adjusted y-screen values for a,b and c }
- ay := adjy(mat[i,j].y,mat[i,j].z);
- by := adjy(mat[i+1,j+1].y,mat[i+1,j+1].z);
- cy := adjy(mat[i+1,j].y,mat[i+1,j].z);
-
- { plot the lines }
-
- draw(ax,ay,bx,by,1);
- draw(ax,ay,cx,cy,1);
- draw(bx,by,cx,cy,1);
- end;
-
- procedure init_matrix;
- begin
- mat[1,1].x := 0.00;
- mat[1,1].y := 0.00;
- mat[1,1].z := 0.00;
-
- mat[maxt,1].x := 100.00;
- mat[maxt,1].y := 0.00;
- mat[maxt,1].z := 0.00;
-
- mat[maxt,maxt].x := 50.00;
- mat[maxt,maxt].y := 86.60;
- mat[maxt,maxt].z := 0.00;
- end;
-
- procedure adjust_landscape;
- { adjust the coordinates for tilted down viewing of surface }
- var i,j : integer;
- depth : real;
- begin
- { rotate the rear up 30 degrees }
- for i := 1 to maxt do
- for j := i to maxt do
- begin
- depth := 87.00 - mat[j,i].y;
- mat[j,i].z := mat[j,i ].z + (depth*0.58);
- end;
-
- { raise all z up from sea level }
- for i := 1 to maxt do
- for j := i to maxt do
- mat[j,i].z := mat[j,i].z + 15.00;
- end;
-
- procedure draw_matrix;
- var i,j : integer;
- begin
- for i := 1 to maxt-1 do
- for j := i to maxt-1 do
- begin
- plot_triangle(j,i);
- end;
- end;
-
- procedure calc_matrix;
- { calculate the triangular matrix (1,1)-(max,max)-(max,1) }
- begin
- dofold(1,1,maxt,maxt,maxt,1);
- end;
-
-
- begin
- {$U+}
- ClrScr;
- GotoXY(15,10);
- Writeln('*** *** *** FRACTAL LANDSCAPES *** *** ***');
- GotoXY(15,13);
- Writeln(' By Scott R. Burke');
- GotoXY(15,22);
- Writeln(' ** Press any key to begin **');
-
- while not (keypressed) do
- delay(10);
-
- randomize;
- graphmode;
- palette(1);
-
- while keypressed do
- read(kbd,ch); { flush the keyboard buffer }
-
- { draw a landscape }
- Writeln('Generating landscape, please wait ....');
- init_matrix;
- calc_matrix;
- adjust_landscape;
- graphmode;
- draw_matrix;
-
- Gotoxy(1,1);
- Writeln('Press a key to quit');
- Repeat until keypressed;
- Textmode;
- end.